package com.common.user.controller;

import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.common.user.domain.Message;
import com.common.user.domain.User;
import com.common.user.repository.RoleRepository;
import com.common.user.repository.UserRepository;
import com.common.user.service.UserService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;

/**
 * user api
 * @author enbool
 *
 */
@Api(description = "Manage User")
@RestController
@RequestMapping(value = "/users")
public class UserController {
		
	@Autowired
	UserRepository userRepository;
	@Autowired
	UserService userService;
	@Autowired
	RoleRepository roleRepository;
	@Autowired
	PasswordEncoder BCryptPasswordEncoder;	
	
	
	@ApiOperation(value = "Register a user")
	@PostMapping
	public Message create(@RequestBody User user) throws Exception {
		
		userService.register(user);		
		return new Message("Success Register a user."); 
	}
	
	
	@ApiOperation(value = "Delete a user")
	@ApiImplicitParam(name = "id", value = "The id of the user to delete.")
	@DeleteMapping(value = "/{id:\\d+}")
	public void delete(@PathVariable Long id) {
		
		userRepository.delete(id);
	}
	

	@ApiOperation(value = "Update a user")
	@PutMapping
	public User update(@RequestBody User user) {
		
		user.setPassword(BCryptPasswordEncoder.encode(user.getPassword()));
		return userRepository.save(user);
	}
	
	/*@ApiOperation(value = "List of Users")
	@GetMapping
	public List<User> findAll() {
		
		return userRepository.findAll();
	}*/
	
	@ApiOperation(value = "Get a user")
	@ApiImplicitParam(name = "id", value = "The id of the user to get.")
	@GetMapping(value = "/{id:\\d+}")
	public User findOne(@PathVariable Long id) {
		
		return userRepository.findOne(id);
	}
	
	@ApiOperation(value = "Reset password")
	@ApiImplicitParam(name = "userInfo", value = "The username, email or phone of the user to reset password")
	@GetMapping(value = "/reset-password")
	public Message resetPassword(@RequestParam String userInfo) throws Exception {		
		
		return userService.resetPassword(userInfo);
	}
	
	@ApiOperation(value = "Update password")
	@ApiImplicitParam(name = "password", value = "The password of the user to update")
	@PutMapping(value = "/update-password")
	public void updatePassword(@RequestBody Map<String, String> params, HttpServletRequest request) {		
		
		userService.updatePassword(request, params.get("password"));
	}
	
	@ApiOperation(value = "List of Users")
	@ApiImplicitParams({
	    @ApiImplicitParam(name = "username", dataType = "string", value = "Only return user with the given username.", paramType = "query"),
	    @ApiImplicitParam(name = "email", dataType = "string", value = "Only return user with the given email.", paramType = "query"),
	    @ApiImplicitParam(name = "name", dataType = "string", value = "Only return user with a name like the given name.", paramType = "query"),
	    @ApiImplicitParam(name = "phone", dataType = "string", value = "Only return user with the given phone.", paramType = "query")	 
	})
	@GetMapping
	public List<User> query(@ApiParam(hidden = true) @RequestParam Map<String, String> allRequestParams) {
		
		return userService.query(allRequestParams);
	}
	
	@ApiOperation(value = "Get the current signin user")
	@GetMapping("/me")
	public User me(HttpServletRequest request) {
		
		return userService.getCurrentUser(request);
	}
}
